﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace MyWCFServices.RealRestaurantService
{

    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
    public class RestaurantService : IRestaurantService
    {
        private void DumpException(Exception exc, string functionName)
        {
            if (exc.Message != null)
            {
                System.Console.WriteLine("Error in {0}(): {1}", functionName, exc.Message);
                System.Console.WriteLine("exception source: {0}", exc.Source);
                System.Console.WriteLine("stack trace: {0}", exc.StackTrace);
                if (exc.InnerException != null)
                {
                    System.Console.WriteLine(exc.InnerException.ToString());
                }
            }
        }

        public bool TestConnection()
        {
            return true;
        }

        /* ---------------------------------------------------------------------------- */
        /* Asztalkezelő függvények                                                      */
        /* ---------------------------------------------------------------------------- */

        public Asztal GetTable(Guid id)
        {
            Database1Entities1 context = null;
            try
            {
                context = new Database1Entities1();
                var asztalEntity = (from p
                                    in context.Asztal
                                    where p.id == id
                                    select p).FirstOrDefault();

                if (asztalEntity != null)
                    return TranslateAsztalEntityToAsztal(asztalEntity);
                else
                    throw new Exception("Invalid table id");
            }
            catch (Exception exc)
            {
                DumpException(exc, "GetTable");
                throw exc;
            }
            finally
            {
                context.Dispose();
            }

        }

        public Guid AddTable(Asztal asztal)
        {
            Database1Entities1 context = null;

            int result = -1;
            try
            {
                AsztalEntity asztalEntity = new AsztalEntity();
                if (asztal.AsztalID == null)//Átírva Solt által. Új asztal felvételét nehezíti, ha itt generálódik az id.
                {
                    asztalEntity.id = Guid.NewGuid();
                }
                else
                {
                    asztalEntity.id = asztal.AsztalID; // Ha van idje, ne adjunk másikat...
                }
                asztalEntity.magassag = asztal.AsztalMagassag;
                asztalEntity.szelesseg = asztal.AsztalSzelesseg;
                asztalEntity.x = asztal.AsztalX;
                asztalEntity.y = asztal.AsztalY;
                asztalEntity.nev = asztal.AsztalName;

                context = new Database1Entities1();
                context.Asztal.AddObject(asztalEntity);
                result = context.SaveChanges();
                Console.WriteLine("AddTable(): added " + result + " record(s).");
                return asztalEntity.id;
            }
            catch (Exception exc)
            {
                DumpException(exc, "AddTable");
            }
            finally
            {
                context.Dispose();
            }

            return Guid.Empty;
        }

        public bool DeleteTable(Asztal asztal)
        {
            bool ret = false;
            Database1Entities1 context = null;
            int result = -1;
            try
            {
                context = new Database1Entities1();
                var asztalEntity = (from p
                                    in context.Asztal
                                    where p.id == asztal.AsztalID
                                    select p).FirstOrDefault();

                if (asztalEntity != null)
                    context.Asztal.DeleteObject(asztalEntity);

                result = context.SaveChanges();
                Console.WriteLine("DeleteTable(): deleted " + result + " record(s).");
                ret = true;
            }
            catch (Exception exc)
            {
                ret = false;
                DumpException(exc, "DeleteTable");
            }
            finally
            {
                context.Dispose();
            }

            return ret;
        }

        public Asztal[] GetAllTables()
        {
            List<Asztal> asztalList = new List<Asztal>();
            Database1Entities1 context = null;
            try
            {
                context = new Database1Entities1();
                var asztalEntities = (from p
                                     in context.Asztal
                                     select p);

                if (asztalEntities.Count() > 0)
                {
                    foreach (AsztalEntity asztalEntity in asztalEntities)
                    {
                        asztalList.Add(TranslateAsztalEntityToAsztal(asztalEntity));
                    }
                }
            }
            catch (Exception exc)
            {
                DumpException(exc, "GetAllTables");
            }
            finally
            {
                context.Dispose();
            }

            return asztalList.ToArray();
        }

        private Asztal TranslateAsztalEntityToAsztal(AsztalEntity asztalEntity)
        {
            Asztal asztal = new Asztal();
            asztal.AsztalID = asztalEntity.id;
            asztal.AsztalMagassag = asztalEntity.magassag;
            if (!string.IsNullOrEmpty(asztalEntity.nev))
                asztal.AsztalName = asztalEntity.nev;
            else
                asztal.AsztalName = "Unnamed table";
            asztal.AsztalSzelesseg = asztalEntity.szelesseg;
            asztal.AsztalX = asztalEntity.x;
            asztal.AsztalY = asztalEntity.y;
            asztal.AsztalTetelek = new List<Arak>().ToArray();
            return asztal;
        }

        public bool UpdateTable(Asztal asztal)
        {
            bool ret = false;
            int result = -1;
            Database1Entities1 context = null;

            try
            {
                context = new Database1Entities1();
                var asztalEntity = (from p
                                    in context.Asztal
                                    where p.id == asztal.AsztalID
                                    select p).FirstOrDefault();

                if (asztalEntity == null)
                    throw new Exception("Table entity not found! Invalid table id?");

                //nem módosíthatjuk!
                //asztalEntity.id = asztal.AsztalID;
                asztalEntity.magassag = asztal.AsztalMagassag;
                asztalEntity.szelesseg = asztal.AsztalSzelesseg;
                asztalEntity.x = asztal.AsztalX;
                asztalEntity.y = asztal.AsztalY;
                asztalEntity.nev = asztal.AsztalName;

                result = context.SaveChanges();
                Console.WriteLine("UpdateTable(): saved " + result + " record(s).");
                ret = true;
            }
            catch (Exception exc)
            {
                ret = false;
                DumpException(exc, "UpdateTable");
            }
            finally
            {
                context.Dispose();
            }

            return ret;
        }

        /* ---------------------------------------------------------------------------- */
        /* Fogyasztási cikk kezelő függvények                                           */
        /* ---------------------------------------------------------------------------- */

        public FogyasztasiCikk GetFogyasztasiCikk(Guid id)
        {
            Database1Entities1 context = null;
            try
            {
                context = new Database1Entities1();
                var fogyasztasiCikkEntity = (from p
                                             in context.FogyasztasiCikk
                                             where p.id == id
                                             select p).FirstOrDefault();

                if (fogyasztasiCikkEntity != null)
                    return TranslateFogyasztasiCikkEntityToFogyasztasiCikk(fogyasztasiCikkEntity);
                else
                    throw new Exception("Invalid fogyasztasiCikk id");
            }
            catch (Exception exc)
            {
                DumpException(exc, "GetFogyasztasiCikk");
                throw exc;
            }
            finally
            {
                context.Dispose();
            }
        }

        public List<FogyasztasiCikk> GetAllFogyasztasiCikkek()
        {
            List<FogyasztasiCikk> fogyasztasiCikkList = new List<FogyasztasiCikk>();
            Database1Entities1 context = null;

            try
            {
                context = new Database1Entities1();
                var fogyasztasiCikkEntities = (from p
                                               in context.FogyasztasiCikk
                                               select p);

                if (fogyasztasiCikkEntities.Count() > 0)
                {
                    foreach (FogyasztasiCikkEntity fogyasztasiCikkEntity in fogyasztasiCikkEntities)
                    {
                        fogyasztasiCikkList.Add(TranslateFogyasztasiCikkEntityToFogyasztasiCikk(fogyasztasiCikkEntity));
                    }
                }

            }
            catch (Exception exc)
            {
                DumpException(exc, "GetAllFogyasztasiCikkek");
            }
            finally
            {
                context.Dispose();
            }

            return fogyasztasiCikkList;
        }

        private FogyasztasiCikk TranslateFogyasztasiCikkEntityToFogyasztasiCikk(FogyasztasiCikkEntity fogyasztasiCikkEntity)
        {
            FogyasztasiCikk fogyasztasiCikk = new FogyasztasiCikk();
            fogyasztasiCikk.FogyasztasiCikkID = fogyasztasiCikkEntity.id;
            fogyasztasiCikk.FogyasztasiCikkNev = fogyasztasiCikkEntity.nev;
            fogyasztasiCikk.FogyasztasiCikkTipus = (FogyasztasiCikkTipus)fogyasztasiCikkEntity.tipus;
            fogyasztasiCikk.FogyasztasiCikkAr = fogyasztasiCikkEntity.ar;
            return fogyasztasiCikk;
        }

        public bool UpdateFogyasztasiCikk(FogyasztasiCikk fogyasztasiCikk)
        {
            bool ret = false;
            Database1Entities1 context = null;
            
            int result = -1;
            try
            {
                context = new Database1Entities1();

                var fogyasztasiCikkEntity = (from p
                                             in context.FogyasztasiCikk
                                             where p.id == fogyasztasiCikk.FogyasztasiCikkID
                                             select p).FirstOrDefault();

                if (fogyasztasiCikkEntity == null)
                    throw new Exception("Fogyasztasi cikk Entity not found! Invalid id?");

                //nem módosíthatjuk!
                //fogyasztasiCikkEntity.id = fogyasztasiCikk.FogyasztasiCikkID;
                fogyasztasiCikkEntity.ar = fogyasztasiCikk.FogyasztasiCikkAr;
                fogyasztasiCikkEntity.nev = fogyasztasiCikk.FogyasztasiCikkNev;
                fogyasztasiCikkEntity.tipus = (int)fogyasztasiCikk.FogyasztasiCikkTipus;

                result = context.SaveChanges();
                Console.WriteLine("UpdateFogyasztasiCikk(): saved " + result + " record(s).");
                ret = true;
            }
            catch (Exception exc)
            {
                ret = false;
                DumpException(exc, "UpdateFogyasztasiCikk");
            }
            finally
            {
                context.Dispose();
            }

            return ret;
        }

        public bool AddFogyasztasiCikk(FogyasztasiCikk fogyasztasiCikk)
        {
            bool ret = false;
            Database1Entities1 context = null;

            int result = -1;
            try
            {
                context = new Database1Entities1();
                FogyasztasiCikkEntity fogyasztasiCikkEntity = new FogyasztasiCikkEntity();
                //fogyasztasiCikkEntity.id = context.FogyasztasiCikk.NextId(f => f.id);
                fogyasztasiCikkEntity.id = Guid.NewGuid();
                fogyasztasiCikkEntity.ar = fogyasztasiCikk.FogyasztasiCikkAr;
                fogyasztasiCikkEntity.nev = fogyasztasiCikk.FogyasztasiCikkNev;
                fogyasztasiCikkEntity.tipus = (int)fogyasztasiCikk.FogyasztasiCikkTipus;
                context.FogyasztasiCikk.AddObject(fogyasztasiCikkEntity);
                result = context.SaveChanges();
                Console.WriteLine("AddFogyasztasiCikk(): added " + result + " record(s).");
                ret = true;
            }
            catch (Exception exc)
            {
                ret = false;
                DumpException(exc, "AddFogyasztasiCikk");
            }
            finally
            {
                context.Dispose();
            }

            return ret;
        }

        public bool DeleteFogyasztasiCikk(FogyasztasiCikk fogyasztasiCikk)
        {
            bool ret = false;
            Database1Entities1 context = null;
            int result = -1;

            try
            {
                context = new Database1Entities1();
                var fogyasztasiCikkEntity = (from p
                                             in context.FogyasztasiCikk
                                             where p.id == fogyasztasiCikk.FogyasztasiCikkID
                                             select p).FirstOrDefault();

                if (fogyasztasiCikkEntity != null)
                    context.FogyasztasiCikk.DeleteObject(fogyasztasiCikkEntity);

                result = context.SaveChanges();
                Console.WriteLine("DeleteFogyasztasiCikk(): deleted " + result + " record(s).");
                ret = true;
            }
            catch (Exception exc)
            {
                ret = false;
                DumpException(exc, "DeleteFogyasztasiCikk");
            }
            finally
            {
                context.Dispose();
            }

            return ret;
        }

        /* ---------------------------------------------------------------------------- */
        /* Étterem kezelő függvények                                                    */
        /* ---------------------------------------------------------------------------- */

        private Etterem TranslateEtteremEntityToEtterem(EtteremEntity etteremEntity)
        {
            Etterem etterem = new Etterem();
            etterem.EtteremID = etteremEntity.id;
            etterem.EtteremMagassag = etteremEntity.magassag;
            etterem.EtteremSzelesseg = etteremEntity.szelesseg;
            etterem.EtteremNev = etteremEntity.name;
            return etterem;
        }

        public Etterem GetEtterem()
        {
            Database1Entities1 context = null;
            try
            {
                context = new Database1Entities1();
                var etteremEntity = (from p
                                    in context.Etterem
                                    select p).FirstOrDefault();

                if (etteremEntity != null)
                    return TranslateEtteremEntityToEtterem(etteremEntity);
                else
                    throw new Exception("Database is not initialized!");
            }
            catch (Exception exc)
            {
                DumpException(exc, "GetEtterem");
                throw exc;
            }
            finally
            {
                context.Dispose();
            }

        }


        public bool SetEtterem(Etterem etterem)
        {
            bool ret = false;
            Database1Entities1 context = null;
            int result = -1;

            try
            {
                context = new Database1Entities1();
                var etteremEntity = (from p
                                     in context.Etterem
                                     select p).FirstOrDefault();

                if (etteremEntity == null)
                    throw new Exception("Database is not initialized!");

                //nem módosíthatjuk!
                //etteremEntity.id = etterem.EtteremID;
                etteremEntity.name = etterem.EtteremNev;
                etteremEntity.szelesseg = etterem.EtteremSzelesseg;
                etteremEntity.magassag = etterem.EtteremMagassag;

                result = context.SaveChanges();
                Console.WriteLine("SetEtterem(): saved " + result + " record(s).");
                ret = true;
            }
            catch (Exception exc)
            {
                ret = false;
                DumpException(exc, "SetEtterem");
                throw exc;
            }
            finally
            {
                context.Dispose();
            }

            return ret;
        }

        /* ---------------------------------------------------------------------------- */
        /* Üzemeltetői függvények                                                       */
        /* ---------------------------------------------------------------------------- */

        public Guid Rendeles(Asztal asztal)
        {
            Guid rendelesGuid = Guid.Empty;
            Database1Entities1 context = new Database1Entities1();

            int result = -1;
            try
            {
                RendelesEntity rendelesEntity = new RendelesEntity();
                rendelesEntity.id = Guid.NewGuid();
                rendelesEntity.AsztalEntity_id = asztal.AsztalID;
                rendelesEntity.datum = DateTime.Now;
                rendelesEntity.osszeg = 0.0f;
                Arak[] arak = asztal.AsztalTetelek;
                if (arak != null)
                {
                    if (arak.Length != 0)
                    {
                        foreach (Arak ar in arak)
                        {
                            rendelesEntity.osszeg += ar.Ar;
                        }
                    }
                }
                rendelesGuid = rendelesEntity.id;
                context.Rendeles.AddObject(rendelesEntity);
                result = context.SaveChanges();
                Console.WriteLine("Rendeles(): saved " + result + " record(s).");

                if (result > 0)
                {
                    if (arak != null)
                    {
                        if (arak.Length != 0)
                        {
                            foreach (Arak ar in arak)
                            {
                                RendelesAdatokEntity rae = new RendelesAdatokEntity();
                                rae.id = Guid.NewGuid();
                                rae.RendelesEntity_id = rendelesEntity.id;
                                rae.cikknev = ar.Tetel;
                                rae.cikkar = ar.Ar;
                                rae.cikkmennyiseg = 1;
                                context.RendelesAdatok.AddObject(rae);
                                result = context.SaveChanges();
                                Console.WriteLine("Rendeles(): saved " + result + " metadata record(s).");
                            }
                        }
                    }
                }

                //rendelesGuid = null;
                
            }
            catch (Exception exc)
            {
                rendelesGuid = Guid.Empty;
                DumpException(exc, "Rendeles");

            }
            finally
            {
                context.Dispose();
            }

            return rendelesGuid;
        }

        public string Szamla(Guid rendelesID)
        {
            string szamlaStr = "";
            Database1Entities1 context = null;
            try
            {
                string etteremNev = this.GetEtterem().EtteremNev;
                context = new Database1Entities1();

                RendelesEntity re = (from p
                                     in context.Rendeles
                                     where p.id == rendelesID
                                     select p).FirstOrDefault();

                Asztal asztal = this.GetTable(re.AsztalEntity_id);

                var raeList = (from p
                               in context.RendelesAdatok
                               where p.RendelesEntity_id == re.id
                               select p).ToList();

                string header = etteremNev + " - Számla<br/>";

                string body = "";
                body += "Dátum: " + re.datum.ToLongDateString() + " " + re.datum.ToLongTimeString() + "<br/>";
                //body += "Asztal: " + asztal.AsztalSzam + "<br/>";
                body += "<br/>";
                body += "Tételek: <br/>";
                double osszeg = 0.0f;
                foreach (RendelesAdatokEntity rae in raeList)
                {
                    body += rae.cikknev + ", " + rae.cikkar + " Ft, " + rae.cikkmennyiseg + " db = " + (double)(rae.cikkar * rae.cikkmennyiseg) + " Ft<br/>";
                    osszeg += (double)(rae.cikkar * rae.cikkmennyiseg);
                }

                body += "<br/>";
                body += "Összesen: " + osszeg + " Ft<br/>";
                body += "<br/>";
                body += "<br/>";

                string footer = "Köszönjük, hogy a vendégünk volt!<br/>";

                szamlaStr = header + body + footer;
            }
            catch (Exception exc)
            {
                DumpException(exc, "Szamla");
            }
            finally
            {
                context.Dispose();
            }

            return szamlaStr;
        }


        /* ---------------------------------------------------------------------------- */
        /* Foglalással kapcsolatos függvények                                           */
        /* ---------------------------------------------------------------------------- */

        private Foglalas TranslateFoglalasEntityToFoglalas(FoglalasEntity foglalasEntity)
        {
            Foglalas foglalas = new Foglalas();
            foglalas.AsztalID = foglalasEntity.AsztalEntity_id;
            foglalas.FoglalasFo = (int)foglalasEntity.fo;
            foglalas.FoglalasID = foglalasEntity.id;
            foglalas.FoglalasIdo = foglalasEntity.ido;
            foglalas.FoglalasMegjegyzes = foglalasEntity.megjegyzes;
            foglalas.FoglalasNev = foglalasEntity.nev;
            return foglalas;
        }

        public Foglalas[] GetFoglalasList(Guid asztalID)
        {
            List<Foglalas> foglalasLista = null;
            Database1Entities1 context = null;
            try
            {
                context = new Database1Entities1();
                foglalasLista = new List<Foglalas>();

                var foglalasok = (from p
                                 in context.Foglalas
                                 where p.AsztalEntity_id == asztalID
                                 select p);

                if (foglalasok.Count() > 0)
                {
                    foreach (FoglalasEntity foglalasEntity in foglalasok)
                    {
                        foglalasLista.Add(TranslateFoglalasEntityToFoglalas(foglalasEntity));
                    }
                }

            }
            catch (Exception exc)
            {
                DumpException(exc, "GetFoglalasList");
                return new List<Foglalas>().ToArray();
            }
            finally
            {
                context.Dispose();
            }
            return foglalasLista.ToArray();
        }


        public bool SetFoglalasList(Guid asztalID, Foglalas[] foglalasLista)
        {
            int result = -1;
            Database1Entities1 context = null;
            try
            {
                context = new Database1Entities1();
                var foglalasok = (from p
                                 in context.Foglalas
                                  where p.AsztalEntity_id == asztalID
                                  select p);

                if (foglalasok.Count() > 0)
                {
                    foreach (FoglalasEntity foglalasEntity in foglalasok)
                    {
                        context.Foglalas.DeleteObject(foglalasEntity);
                        result = context.SaveChanges();
                        Console.WriteLine("SetFoglalasList(): deleted " + result + " record(s).");
                    }
                }

                foreach (Foglalas f in foglalasLista)
                {
                    FoglalasEntity fe = new FoglalasEntity();
                    fe.id = Guid.NewGuid();
                    fe.AsztalEntity_id = asztalID;
                    fe.fo = (int)f.FoglalasFo;
                    fe.ido = f.FoglalasIdo;
                    fe.megjegyzes = f.FoglalasMegjegyzes;
                    fe.nev = f.FoglalasNev;
                    context.Foglalas.AddObject(fe);
                    result = context.SaveChanges();
                    Console.WriteLine("SetFoglalasList(): saved " + result + " record(s).");
                }
            }
            catch (Exception exc)
            {
                DumpException(exc, "SetFoglalasList");
            }
            finally
            {
                context.Dispose();
            }
            return true;
        }
    }
}
